package com.team.game.Game;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PathMeasure;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.RectF;

import com.team.game.Assets;
import com.team.game.framework.Game;
import com.team.game.framework.Level;
import com.team.game.framework.impl.MainActivity;
import com.team.game.framework.impl.SurfaceThread;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import static com.team.game.framework.impl.Scale_X_Y.Scale_X;
import static com.team.game.framework.impl.Scale_X_Y.Scale_Y;
import static com.team.game.framework.impl.Scale_X_Y.Size_X;
import static com.team.game.framework.impl.Scale_X_Y.Size_Y;


public class Levels implements Level {

    public ArrayList<Wave> arrayListMob;
    public int Num_Wave; //кількість хвиль

    public float Time;
    public float Time_Wave_Start[];
    public float Time_Wave_End[];

    public float x_tower;      // поля для реалізації методу searchMob
    public float y_tower;      // поля для реалізації методу searchMob
    public int Level_Num_Wave, Level_Num_Mob;  // поля для реалізації методу searchMob
    public PointF Level_Point = new PointF ();  // поля для реалізації методу searchMob

    private Point point = new Point();//точка яка повертається методом searchMob

    public Levels (Game game, int Num_Level) {

        //створюємо патимейкер
        PathMaker pathMaker = new PathMaker();

        Time = 0;

        InputStream inputStream;
        try {
            inputStream = MainActivity.manager.open ("Picture/test_pause_menu.png");
            Assets.pause = Bitmap.createScaledBitmap (BitmapFactory.decodeStream (inputStream), (int) Size_X, (int) Size_Y, false);

            inputStream = MainActivity.manager.open ("Picture/Sprites/test_mob_1.png");
            Assets.orc = Bitmap.createScaledBitmap (BitmapFactory.decodeStream (inputStream), (int) (576 * Scale_X), (int) (320 * Scale_Y), false);

            inputStream = MainActivity.manager.open ("Picture/Sprites/test_mob_4.png");
            Assets.yarik = Bitmap.createScaledBitmap (BitmapFactory.decodeStream (inputStream), (int) (576 * Scale_X), (int) (320 * Scale_Y), false);

        } catch (IOException e) {
            e.printStackTrace ();
        }

        PathMeasure pathMeasure[] = pathMaker.makeLevel (Num_Level);

        switch (Num_Level) {
            case 1: {

                /* int Num_Mob - кількість мобів в хвилі,
                 * int[] Mob_Kind - масив типів моба(орк=1, мачула спрайт=2)
                 * float[] Mob_Time - час виходу кожного моба
                 * int[] Num_Path - шлях по якому буде йти кожен моб
                 * PathMeasure pathMeasure[] - можливі шляхи по яким може йти моб
                 */


                Num_Wave = 4;  //кількість хвиль
                Time_Wave_Start = new float[]{0f, 30f, 60f, 90f, /*60f*/};// час початку хвилі
                Time_Wave_End = new float[]{40f, 80f, 120f, /*75f,*/ 300f};// час кінця хвилі

                arrayListMob = new ArrayList<>(Num_Wave);

                arrayListMob.add(0, new Wave(6, new int[]{1, 1, 1, 1, 1, 1}, new float[]{0.2f, 1.2f, 2.2f, 0.8f, 1.8f, 2.8f}, new int[]{0, 0, 0, 0, 0, 0}, pathMeasure));
                arrayListMob.add(1, new Wave(8, new int[]{0, 0, 0, 0, 1, 1, 1, 1}, new float[]{0.2f, 1.2f, 2.2f, 2.4f, 1.8f, 2.8f, 3.8f, 4, 2f}, new int[]{0, 0, 0, 0, 0, 0, 0, 0}, pathMeasure));
                arrayListMob.add(2, new Wave(12, new int[]{1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, new float[]{0.2f, 1.2f, 2.2f, 2.6f, 2.8f, 3.8f, 4.8f, 2f, 3f, 4f, 5f, 4.6f}, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, pathMeasure));
                arrayListMob.add(3, new Wave(20, new int[]{1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}, new float[]{0.2f, 1.2f, 2.2f, 3.4f, 1.8f, 2.8f, 3.8f, 1f, 2f, 3f, 4f, 5f, 3.2f, 2.2f, 4.2f, 5.5f, 3.5f, 4.5f, 3.7f, 4.7f}, new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, pathMeasure));
                //arrayListMob.add(1, new Boss_Wave(1, pathMeasure));
                break;
            }
            case 2: {


                Num_Wave = 4;  //кількість хвиль
                Time_Wave_Start = new float[]{0f, 30f, 60f, 90f, /*60f*/};// час початку хвилі
                Time_Wave_End = new float[]{40f, 80f, 120f, /*75f,*/ 300f};// час кінця хвилі

                arrayListMob = new ArrayList<>(Num_Wave);

                arrayListMob.add(0, new Wave(6, new int[]{1, 1, 1, 1, 1, 1}, new float[]{0.2f, 0.2f, 0.2f, 0.8f, 0.8f, 0.8f}, new int[]{0, 1, 2, 0, 1, 2}, pathMeasure));
                arrayListMob.add(1, new Wave(8, new int[]{0, 0, 0, 0, 1, 1, 1, 1}, new float[]{0.2f, 0.2f, 0.2f, 0.4f, 0.8f, 0.8f, 0.8f, 1f}, new int[]{1, 2, 0, 1, 1, 2, 0, 1}, pathMeasure));
                arrayListMob.add(2, new Wave(12, new int[]{1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, new float[]{0.2f, 0.2f, 0.2f, 0.4f, 0.8f, 0.8f, 0.8f, 1f, 1f, 2f, 2f, 2f}, new int[]{1, 2, 0, 1, 1, 2, 0, 1, 0, 1, 2, 0}, pathMeasure));
                arrayListMob.add(3, new Wave(20, new int[]{1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}, new float[]{0.2f, 0.2f, 0.2f, 0.4f, 0.8f, 0.8f, 0.8f, 1f, 1f, 2f, 2f, 2f, 3f, 3f, 3f, 3.5f, 3.5f, 3.5f, 3.7f, 3.7f}, new int[]{1, 2, 0, 1, 1, 2, 0, 1, 0, 1, 2, 0, 1, 2, 0, 1, 0, 1, 2, 0}, pathMeasure));
                //arrayListMob.add(1, new Boss_Wave(1, pathMeasure));
                break;
            }
            case 3: {
                Num_Wave = 4;  //кількість хвиль
                Time_Wave_Start = new float[]{0f, 30f, 60f, 90f, /*60f*/};// час початку хвилі
                Time_Wave_End = new float[]{40f, 80f, 120f, /*75f,*/ 300f};// час кінця хвилі

                arrayListMob = new ArrayList<> (Num_Wave);

                arrayListMob.add (0, new Wave (6, new int[]{1, 1, 1, 1, 1, 1}, new float[]{0.2f, 0.2f, 0.2f, 0.8f, 0.8f, 0.8f}, new int[]{0, 1, 0, 0, 1, 1}, pathMeasure));
                arrayListMob.add (1, new Wave (8, new int[]{0, 0, 0, 0, 1, 1, 1, 1}, new float[]{0.2f, 0.2f, 0.2f, 0.4f, 0.8f, 0.8f, 0.8f, 1f}, new int[]{0, 1, 1, 0, 0, 1, 0, 1}, pathMeasure));
                arrayListMob.add (2, new Wave (12, new int[]{1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, new float[]{0.2f, 0.2f, 0.2f, 0.4f, 0.8f, 0.8f, 0.8f, 1f, 1f, 2f, 2f, 2f}, new int[]{1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0}, pathMeasure));
                arrayListMob.add (3, new Wave (20, new int[]{1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}, new float[]{0.2f, 0.2f, 0.2f, 0.4f, 0.8f, 0.8f, 0.8f, 1f, 1f, 2f, 2f, 2f, 3f, 3f, 3f, 3.5f, 3.5f, 3.5f, 3.7f, 3.7f}, new int[]{0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}, pathMeasure));
                //arrayListMob.add(1, new Boss_Wave(1, pathMeasure));
                break;
            }
        }

    }

    public void update () {
        Time += SurfaceThread.deltaTime;
        for (int i = 0; i < Num_Wave; i++) {
            if (Time > Time_Wave_Start[i] && Time < Time_Wave_End[i]) // оновлюємо хвилю мобів, тільки якщо настав її час
                arrayListMob.get(i).WaveUpdate();
        }
    }

    public void drawMobs (Canvas canvas) {

        for (int i = 0; i < Num_Wave; i++) {
            if (Time > Time_Wave_Start[i] && Time < Time_Wave_End[i])   // оновлюємо хвилю мобів, тільки якщо настав її час
                arrayListMob.get(i).WaveDraw(canvas);
        }
    }

    public void dispose () {
        for (int i = 0; i < Num_Wave; i++) {
            arrayListMob.get(i).WaveDispose();
        }
        arrayListMob.clear();
    }

    public Point searchMob (RectF pos, float radius, float radius1) {
        x_tower = pos.centerX ();
        y_tower = pos.centerY ();

        Level_Num_Wave = -1;
        Level_Num_Mob = -1;

        for (int i = 0; i < Num_Wave; i++) {
            if (Time > Time_Wave_Start[i] && Time < Time_Wave_End[i]) {
                Level_Point = arrayListMob.get(i).WaveSearchMob(x_tower, y_tower, radius, radius1); // находимо моба з мінімальною відстанню, з активних хвиль
                if (Level_Point.x != -1) { // повернуте значення = -1 моба не знайдено
                    Level_Num_Wave = i; //фіксуємо номер хвилі
                    Level_Num_Mob = (int) Level_Point.x;  //фіксуємо номер моба в хвилі
                    radius = Level_Point.y;// другий параметр повернутої точки, найменша відстань моба в хвилі
                }
            }
        }
        if (Level_Num_Mob == -1) {
            point.set(-1, 0); //якщо моба не знайдено
            return point;
        } else {
            point.set (Level_Num_Wave, Level_Num_Mob);
            return point;
        }
    }

    public RectF getPosition (Point point) {
        return arrayListMob.get(point.x).waveGetPosition(point.y); // метод повертає кординати моба
    }

    public void strike (Point point, float kick) {
        arrayListMob.get(point.x).mobStrike(point.y, kick);
    }

    public void restart() {
        Time = 0;
        for (int i = 0; i < Num_Wave; i++) {
            arrayListMob.get(i).WaveRestart();
        }

    }

//    public void impactOnTheRadius(PointF pointF, float Damage, float Radius) {
//        for (int i = 0; i < Num_Wave; i++) {
//            if (Time > Time_Wave_Start[i] && Time < Time_Wave_End[i]) {
//                arrayListMob.get(i).impactOnTheRadius(pointF, Damage, Radius);
//            }
//        }
//    }

//    public void impactOnDegRect (RectF rectF, float alpha, PointF pnt, float damage) {
//        for (int i = 0; i < Num_Wave; i++) {
//            if (Time > Time_Wave_Start[i] && Time < Time_Wave_End[i]) {
//                arrayListMob.get (i).impactOnDegRect (rectF, alpha, pnt, damage);
//            }
//        }
//    }
}